package cn.xu.tool.big.a;

import cn.xu.tool.big.a.compments.KlineCp;
import cn.xu.tool.big.a.compments.TextReport;
import cn.xu.tool.big.a.compments.TradeRecordCp;
import cn.xu.tool.big.a.compments.transaction.TransactionDialogHalfCp;
import cn.xu.tool.big.a.dto.KLine;
import cn.xu.tool.big.a.dto.TotalReturn;
import cn.xu.tool.big.a.dto.TradeRecord;

import java.util.*;

/**
 * 类名: TransactionMain
 * 描述: TODO
 * 作者: ClarkXu clark2021@qq.com
 * 日期: 2025/7/14
 */
public class TransactionMain {

    static List<TradeRecord> results = new ArrayList<>();

    public static void main(String[] args) throws Exception {
        String startDate = args[0];
        String endDate = args[1];
        String stockCode = args[2];
        double initialCapital = Double.parseDouble(args[3]); // 初始资金10万
        double commissionRate = Double.parseDouble(args[4]); // 佣金率1.354/万
        int shortPeriod = Integer.parseInt(args[5]);
        int longPeriod = Integer.parseInt(args[6]);
        double buyDiscount = Double.parseDouble(args[7]);
        double sellDiscount = Double.parseDouble(args[8]);
        double maxSellDiscount = Double.parseDouble(args[9]);
        double stopLossDiscount = Double.parseDouble(args[10]);
        String frequency = args[11];
        int initTotalPosition = Integer.parseInt(args[12]);
        double initialTotalCost = Double.parseDouble(args[13]);
        double intLastBuyPrice = Double.parseDouble(args[14]);
        boolean t0 = Boolean.parseBoolean(args[15]);
        boolean stopLossHalfSell = Boolean.parseBoolean(args[16]);
        boolean checkIsValidTime = true;
        if(args.length>17){
            checkIsValidTime = Boolean.parseBoolean(args[17]);
        }

        TotalReturn totalReturn = new TotalReturn();
        totalReturn.setInitialCapital(initialCapital);
        totalReturn.setFinalCapital(initialCapital);
        totalReturn.setTotalPosition(initTotalPosition);
        totalReturn.setTotalCost(initialTotalCost);
        totalReturn.setLastBuyPrice(intLastBuyPrice);

        String reportParentPath = System.getProperty("report.parent.path");
        List<TradeRecord> tradeRecordsHis = TradeRecordCp.readRecordFile(reportParentPath, stockCode, startDate, endDate);
        if(tradeRecordsHis!=null&&tradeRecordsHis.size()>0){
            results.addAll(tradeRecordsHis);
            TradeRecord last = tradeRecordsHis.get(tradeRecordsHis.size() - 1);
            if("卖出".equals(last.getOperation())){
                totalReturn.setFinalCapital(last.getTotalAsset());
                totalReturn.setTotalPosition(last.getPosition());
            }
            totalReturn.setTradeCount(tradeRecordsHis.size());
        }

//        {
//            "cash": 7739.400000000001,
//                "date": "2025-08-05 10:20:00",
//                "operation": "卖出",
//                "position": 0,
//                "price": 0.743,
//                "tmpReturnRate": 1.298667226361633,
//                "totalAsset": 7739.400000000001,
//                "volume": 10400
//        }




        transaction(totalReturn, stockCode, startDate, endDate, frequency, initialCapital, initTotalPosition, initialTotalCost, intLastBuyPrice, commissionRate, shortPeriod, longPeriod, buyDiscount, sellDiscount, maxSellDiscount, stopLossDiscount, t0, stopLossHalfSell);

        Timer timer = new Timer();
        // 计算首次执行延迟：确保在每分钟的第15秒触发
        Calendar now = Calendar.getInstance();
        int currentSecond = now.get(Calendar.SECOND);
        long initialDelay = (currentSecond <= 15)
                ? (15 - currentSecond) * 1000L
                : (60 - currentSecond + 15) * 1000L;

        timer.schedule(new CustomTask(totalReturn, startDate, endDate, stockCode, initialCapital, commissionRate,
                shortPeriod, longPeriod, buyDiscount, sellDiscount, maxSellDiscount,
                stopLossDiscount, frequency, initTotalPosition, initialTotalCost, intLastBuyPrice,
                t0, stopLossHalfSell, checkIsValidTime), initialDelay, 60 * 1000);
    }

    private static void transaction(TotalReturn totalReturn, String stockCode, String startDate, String endDate, String frequency, double initialCapital, int initTotalPosition, double initialTotalCost, double intLastBuyPrice, double commissionRate, int shortPeriod, int longPeriod, double buyDiscount, double sellDiscount, double maxSellDiscount, double stopLossDiscount, boolean t0, boolean stopLossHalfSell) throws Exception {
        String klineParentPath = System.getProperty("kline.parent.path");
        List<KLine> kLines = KlineCp.readKlineNowPath(klineParentPath, stockCode, startDate, endDate, frequency);
        TransactionDialogHalfCp.doTransactionBt(kLines,
                initialCapital, initTotalPosition, initialTotalCost, intLastBuyPrice,
                commissionRate, totalReturn,
                shortPeriod, longPeriod, buyDiscount, sellDiscount, maxSellDiscount, stopLossDiscount, t0, stopLossHalfSell, results);
        String reportParentPath = System.getProperty("report.parent.path");
        TextReport.saveTextReportPath(reportParentPath, kLines, results, stockCode, startDate, endDate, totalReturn);
        TradeRecordCp.saveRecordFile(reportParentPath, stockCode, results, startDate, endDate);
    }

    static class CustomTask extends TimerTask {

        String startDate;
        String endDate;
        String stockCode;
        double initialCapital;
        double commissionRate;
        int shortPeriod;
        int longPeriod;
        double buyDiscount;
        double sellDiscount;
        double maxSellDiscount;
        double stopLossDiscount;
        String frequency;
        int initTotalPosition;
        double initialTotalCost;
        double intLastBuyPrice;
        boolean t0;
        boolean stopLossHalfSell;
        TotalReturn totalReturn;

        boolean checkIsValidTime;

        private CustomTask(){
        }

        public CustomTask(TotalReturn totalReturn, String startDate, String endDate, String stockCode, double initialCapital, double commissionRate,
                          int shortPeriod, int longPeriod, double buyDiscount, double sellDiscount, double maxSellDiscount,
                          double stopLossDiscount, String frequency, int initTotalPosition, double initialTotalCost, double intLastBuyPrice,
                          boolean t0, boolean stopLossHalfSell, boolean checkIsValidTime) {
            this.totalReturn = totalReturn;
            this.startDate = startDate;
            this.endDate = endDate;
            this.stockCode = stockCode;
            this.initialCapital = initialCapital;
            this.commissionRate = commissionRate;
            this.shortPeriod = shortPeriod;
            this.longPeriod = longPeriod;
            this.buyDiscount = buyDiscount;
            this.sellDiscount = sellDiscount;
            this.maxSellDiscount = maxSellDiscount;
            this.stopLossDiscount = stopLossDiscount;
            this.frequency = frequency;
            this.initTotalPosition = initTotalPosition;
            this.initialTotalCost = initialTotalCost;
            this.intLastBuyPrice = intLastBuyPrice;
            this.t0 = t0;
            this.stopLossHalfSell = stopLossHalfSell;
            this.checkIsValidTime = checkIsValidTime;
        }

        @Override
        public void run() {
            try {
                Calendar cal = Calendar.getInstance();
                int hour = cal.get(Calendar.HOUR_OF_DAY);
                int minute = cal.get(Calendar.MINUTE);
                int second = cal.get(Calendar.SECOND);
                int secondOfDay = hour * 3600 + minute * 60 + second; // 当前秒数（0点起）

                // 定义时间段（秒数范围）
                int amStart = 9 * 3600 + 29 * 60;  // 9:30:00 (34200秒)
                int amEnd = 11 * 3600 + 31 * 60;    // 11:31:00 (41460秒)
                int pmStart = 13 * 3600;            // 13:00:00 (46800秒)
                int pmEnd = 15 * 3600;              // 15:00:00 (54000秒)

                // 判断当前时间是否在有效时间段内
                boolean isValidTime =
                        (secondOfDay >= amStart && secondOfDay <= amEnd) ||
                                (secondOfDay >= pmStart && secondOfDay <= pmEnd);

                if (!checkIsValidTime||isValidTime) {
                    transaction(totalReturn, stockCode, startDate, endDate, frequency, initialCapital, initTotalPosition, initialTotalCost, intLastBuyPrice, commissionRate, shortPeriod, longPeriod, buyDiscount, sellDiscount, maxSellDiscount, stopLossDiscount, t0, stopLossHalfSell);
                }
            } catch (Exception e) {
                System.err.println("任务执行异常: " + e.getMessage());
            }
        }
    }
}
